﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity;

namespace Services
{
    public class AspectHandlerAttribute : HandlerAttribute
    {
        /// <summary>
        /// 是否需要数据转换,兼容以前的byte[]类型的数据转换
        /// </summary>
        public bool IsDataTransformation { set; get; }

        private bool isReadUserToken = true;

        public bool IsReadUserToken
        {
            get { return isReadUserToken; }
            set { isReadUserToken = value; }
        }

        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new AspectHandler()
            {
                Order = this.Order,
                IsTransformation = this.IsDataTransformation,
                IsReadUserToken = this.IsReadUserToken
            };
        }
    }

    public class AspectHandler : ICallHandler
    {
        private static System.Threading.Mutex _mutex = new System.Threading.Mutex(false);

        // private static System.Threading.Mutex _mutex = new System.Threading.Mutex(true);  //并发访问需要测试是否需要互斥锁
        public int Order { get; set; }

        public bool IsTransformation { private get; set; }
        public bool IsReadUserToken { set; private get; }

        /// <summary>
        /// 通过实现此方法来拦截调用并执行所需的拦截行为
        /// </summary>
        /// <param name="input">调用拦截目标时的输入信息</param>
        /// <param name="getNext">通过行为链来获取下一个拦截行为的委托</param>
        /// <returns>从拦截目标获得的返回信息</returns>
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            try
            {
                _mutex.WaitOne();

                string funName = input.MethodBase.Name;

                LogManagement.Log4netHelper.LogInfo(LogManagement.Log4netType.Info, funName, "LogInfo内容");
                //0.解析参数
                var arrInputs = input.Inputs;
                if (arrInputs.Count > 0)
                {
                    var result = arrInputs[0] as byte[];
                }
                //1.执行方法之前的拦截

                LogManagement.Log4netHelper.LogInfo(LogManagement.Log4netType.Info, funName, "方法执行前拦截到了");
                //2.执行方法
                var messagereturn = getNext()(input, getNext);

                //3.执行方法之后的拦截
                LogManagement.Log4netHelper.LogInfo(LogManagement.Log4netType.Info, funName, "方法执行后拦截到了");
                return messagereturn;
            }
            finally
            {
                _mutex.ReleaseMutex();
            }
        }
    }
}